/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package yoga.algo.coding.binary;

import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author Yogev Montekyo
 */
public class BinaryString
{
    ArrayList<Boolean> m_listBooleans;

    public BinaryString(int size)
    {
        m_listBooleans = new ArrayList<Boolean>(size);
        for (int i = 0; i < size; i++)
        {
            m_listBooleans.add(i, Boolean.FALSE);
        }
    }

    public void setBits(ArrayList<Boolean> listOfBooleans)
    {
        m_listBooleans = listOfBooleans;
    }
    
    public void setBits(BinaryString binaryString)
    {
        this.m_listBooleans = binaryString.m_listBooleans;
    }
    
    public int size()
    {
        return m_listBooleans.size();
    }

    public void setBit(int index, boolean value)
    {
        if (index >= m_listBooleans.size())
        {
            throw new IndexOutOfBoundsException("Selected Bit [" + index + "] is out of bounds [" + m_listBooleans.size() + "]");
        }
        m_listBooleans.set(index, value);
    }

    public Boolean getBit(int index)
    {
        if (m_listBooleans == null)
        {
            throw new IllegalStateException("BinaryString not initialized correctly and cannot be accessed");
        }
        if (index >= m_listBooleans.size())
        {
            throw new IndexOutOfBoundsException("Selected Bit [" + index + "] is out of bounds [" + m_listBooleans.size() + "]");
        }

        return m_listBooleans.get(index);
    }

    public void crossWith(BinaryString binaryString, int crossingIndex) throws IllegalArgumentException
    {
        if (binaryString == null)
        {
            throw new IllegalArgumentException("Cannot cross with null referecnce");
        }

        if (crossingIndex >= binaryString.size())
        {
            throw new IllegalArgumentException("Error, selected index [" + crossingIndex + "] is out of BinaryString bounds [" + binaryString.size() + "]");
        }

        if (m_listBooleans.size() != binaryString.size())
        {
            throw new IllegalArgumentException("BinaryStrings do not match in their size");
        }

        ArrayList<Boolean> thisTruncLeft = new ArrayList<Boolean>();
        ArrayList<Boolean> thisTruncRight = new ArrayList<Boolean>();

        //Before crossing index, left and right strings remains the same
        for (int index = 0; index < crossingIndex; index++)
        {
            thisTruncLeft.add(m_listBooleans.get(index));
            thisTruncRight.add(binaryString.m_listBooleans.get(index));
        }

        //From and after crossing index, left swaps with right string
        for (int index = crossingIndex; index < m_listBooleans.size(); index++)
        {
            thisTruncLeft.add(binaryString.m_listBooleans.get(index));
            thisTruncRight.add(m_listBooleans.get(index));
        }

        //Complete the cross
        this.m_listBooleans = thisTruncLeft;
        binaryString.m_listBooleans = thisTruncRight;
    }

    public void contaminateRandomBit()
    {
        int contaminationIndex = new Random().nextInt(m_listBooleans.size());
        boolean mutatedBit = !m_listBooleans.get(contaminationIndex);
        m_listBooleans.set(contaminationIndex, mutatedBit);
    }

    private void initFromInteger(int integer)
    {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    private int convertToInteger()
    {
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
